package top.lshaci.learning.springboot.web.controller;

import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor;
import org.springframework.web.util.UrlPathHelper;
import top.lshaci.learning.springboot.web.config.MvcConfig;
import top.lshaci.learning.springboot.web.model.Person;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ParameterController
 *
 * @author lshaci
 * @since 1.0.0
 */
@RestController
@RequestMapping("/param")
public class ParameterController {

    @GetMapping("/pathvariable/car/{id}/owner/{username}")
    public Object pathVariable(@PathVariable Long id,
                               @PathVariable String username,
                               @PathVariable Map<String, Object> param
    ) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("username", username);
        map.put("param", param);
        return map;
    }

    @GetMapping("/requestheader")
    public Object requestHeader(@RequestHeader String accept,
                                @RequestHeader Map<String, Object> param
    ) {
        Map<String, Object> map = new HashMap<>();
        map.put("accept", accept);
        map.put("param", param);
        return map;
    }

    @GetMapping("/cookievalue")
    public Object cookieValue(@CookieValue String vipPromorunningtmr) {
        Map<String, Object> map = new HashMap<>();
        map.put("vipPromorunningtmr", vipPromorunningtmr);
        return map;
    }

    @GetMapping("/requestparam")
    public Object requestParam(@RequestParam String name,
                               @RequestParam Integer age,
                               @RequestParam Map<String, Object> param
    ) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        map.put("age", age);
        map.put("param", param);
        return map;
    }

    /**
     * 使用矩阵变量参数
     *
     * <pre>
     *     对于路径的处理，都使用{@link UrlPathHelper}进行解析；
     *     {@link UrlPathHelper}中 removeSemicolonContent 默认为 true，会移除请求路径中分号后的内容
     * </pre>
     * <p>
     * 1、语法：/matrixvariable/{path;low=34;brand=byd,audi,yd}，矩阵变量参数需要绑定在路径变量上
     * 2、开启 {@link MvcConfig} 中的 configurePathMatch 方法 => urlPathHelper.setRemoveSemicolonContent(false);
     * 3、请求：/matrixvariable/path;low=34;brand=byd,audi,yd
     */
    @GetMapping("/matrixvariable/{path}")
    public Object matrixVariable(@MatrixVariable Integer low,
                                 @MatrixVariable List<String> brand,
                                 @PathVariable String path,
                                 @MatrixVariable Map<String, Object> param
    ) {
        Map<String, Object> map = new HashMap<>();
        map.put("path", path);
        map.put("low", low);
        map.put("brand", brand);
        map.put("param", param);
        // {"path":"path","low":34,"param":{"low":"34","brand":"byd"},"brand":["byd","audi","yd"]}
        return map;
    }

    /**
     * /matrixvariable/1;age=50/2;age=30
     */
    @GetMapping("/matrixvariable/{bossId}/{empId}")
    public Object matrixVariable1(
            @PathVariable Long bossId,
            @MatrixVariable(pathVar = "bossId", name = "age") Integer bossAge,
            @PathVariable Long empId,
            @MatrixVariable(pathVar = "empId", name = "age") Integer empAge
    ) {
        Map<String, Object> map = new HashMap<>();
        map.put("bossId", bossId);
        map.put("bossAge", bossAge);
        map.put("empId", empId);
        map.put("empAge", empAge);
        // {"empId":2,"bossAge":50,"bossId":1,"empAge":30}
        return map;
    }

    /**
     * <pre>
     *     自定义类型参数解析器{@link ServletModelAttributeMethodProcessor}
     *     通过{@link GenericConversionService}获取转换器
     *
     *     使用form表单提交数据：
     *     name: zhangsan
     *     age: 11
     *     birth: 2010/12/19
     *     pet.name: cat
     *     pet.age: 3
     *
     *     使用自定义的 String2PetConverter
     *     name: zhangsan
     *     age: 11
     *     birth: 2010/12/19
     *     pet: cat,3
     * </pre>
     */
    @PostMapping("/person")
    public Object person(Person person) {
        System.err.println(person);
        return person;
    }
}
